/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.controller;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;

import javax.validation.Valid;

import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.admin.dto.ElevatorAttachmentDTO;
import org.springblade.modules.admin.dto.ElevatorAttachmentReportPageDTO;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.enums.ElevatorAttachmentEnum;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.vo.ElevatorAttachmentVO;
import org.springblade.modules.admin.vo.parts.PartWordUrlVo;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.modules.admin.vo.ElevatorAttachmentHistoryVO;
import org.springblade.modules.admin.wrapper.ElevatorAttachmentHistoryWrapper;
import org.springblade.core.boot.ctrl.BladeController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 电梯-附件表，电梯一对多附件, 历史表 控制器
 *
 * @author ysq
 * @since 2024-05-28
 */
@RestController
@AllArgsConstructor
@RequestMapping("sida-maintain-admin/elevator-attachment-history")
@Api(value = "电梯附件表", tags = "电梯附件表")
public class ElevatorAttachmentHistoryController extends BladeController {

	private final IElevatorAttachmentHistoryService elevatorAttachmentHistoryService;

	private final IElevatorAttachmentService elevatorAttachmentService;

	private final IUserService userService;

	private final ElevatorService elevatorService;

	private final IElevatorDetailService elevatorDetailService;

	private final IMaintainPlanContentService planContentService;

	private final IMaintainPlanContentExtService planContentExtService;

	/**
	 * 新增或修改 电梯-附件表，电梯一对多附件
	 * 检验报告
	 */
	@PostMapping("/report/save-or-update")
	@ApiOperationSupport(order = 10)
	@ApiOperation(value = "新增或修改", notes = "传入elevatorAttachmentHistory")
	public R<Boolean> saveOrUpdateReport(@RequestBody ElevatorAttachmentDTO elevatorAttachment) {
		return R.data(elevatorAttachmentService.saveOrUpdate(elevatorAttachment));
	}

	/**
	 * 删除 电梯-附件表，电梯一对多附件, 历史表
	 * 电梯使用证
	 */
	@PostMapping("/certify/remove")
	@ApiOperationSupport(order = 21)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R<Boolean> remove(@RequestBody List<String> ids) {
		List<Long> targetIds = new ArrayList<>();
		for (String id : ids) {
			targetIds.add(Long.parseLong(id));
		}
		targetIds.forEach(elevatorAttachmentHistoryService::removeById);
		return R.status(true);
	}


	/**
	 * 删除 电梯-附件表，电梯一对多附件, 历史表
	 * 电梯使用证
	 */
	@GetMapping("/certify/remove/v2")
	@ApiOperationSupport(order = 21)
	@ApiOperation(value = "逻辑删除v2", notes = "传入ids")
	public R<Boolean> removeV2(Long id) {
		ElevatorAttachmentHistory attachmentHistory = elevatorAttachmentHistoryService.getById(id);
		Elevator elevator = elevatorService.getById(attachmentHistory.getElevatorId());
		List<ElevatorAttachmentHistory> historyList = elevatorAttachmentHistoryService.list(Wrappers.<ElevatorAttachmentHistory>lambdaQuery().eq(ElevatorAttachmentHistory::getElevatorId, attachmentHistory.getElevatorId()).orderByDesc(ElevatorAttachmentHistory::getCreateTime));
		historyList.remove(attachmentHistory);
		if (attachmentHistory.getStatus() == ElevatorAttachmentEnum.WB_EXT_IMG.getStatus() || attachmentHistory.getStatus() == ElevatorAttachmentEnum.WB_PHONE_IMG.getStatus() || attachmentHistory.getStatus() == ElevatorAttachmentEnum.ELEVATOR_NUM_IMG.getStatus() || attachmentHistory.getStatus() == ElevatorAttachmentEnum.BX_IMG.getStatus()) {
			Map<Integer, List<ElevatorAttachmentHistory>> listMap = historyList.stream().collect(Collectors.groupingBy(ElevatorAttachmentHistory::getStatus));
			if (attachmentHistory.getStatus() == ElevatorAttachmentEnum.WB_PHONE_IMG.getStatus()) {
				List<ElevatorAttachmentHistory> attachmentHistoryList = listMap.get(ElevatorAttachmentEnum.WB_PHONE_IMG.getStatus());
				List<PartWordUrlVo> partWordUrlVos = new ArrayList<>(1);
				if (attachmentHistoryList != null && attachmentHistoryList.size() > 0) {
					JSONObject jsonObject = JSON.parseObject(attachmentHistoryList.get(0).getAttachment());
					if (elevator.getWbPhoneImg() != null && elevator.getWbPhoneImg().size() > 0) {
						PartWordUrlVo partWordUrlVo = JSON.parseArray(JSON.toJSONString(elevator.getWbPhoneImg()), PartWordUrlVo.class).get(0);
						partWordUrlVo.setUrl(Convert.toStr(jsonObject.get("url")));
						elevator.setWbPhoneImgDate(attachmentHistoryList.get(0).getCreateTime());
						partWordUrlVos.add(partWordUrlVo);
					} else {
						PartWordUrlVo partWordUrlVo = new PartWordUrlVo();
						partWordUrlVo.setUrl(Convert.toStr(jsonObject.get("url")));
						partWordUrlVo.setType("image");
						elevator.setWbPhoneImgDate(attachmentHistoryList.get(0).getCreateTime());
						partWordUrlVos.add(partWordUrlVo);
					}
				}
				elevator.setWbPhoneImg(partWordUrlVos);
				elevatorService.updateById(elevator);
			} else if (attachmentHistory.getStatus() == ElevatorAttachmentEnum.WB_EXT_IMG.getStatus()) {
				List<ElevatorAttachmentHistory> attachmentHistoryList = listMap.get(ElevatorAttachmentEnum.WB_EXT_IMG.getStatus());
				List<PartWordUrlVo> partWordUrlVos = new ArrayList<>(1);
				if (attachmentHistoryList != null && attachmentHistoryList.size() > 0) {
					JSONObject jsonObject = JSON.parseObject(attachmentHistoryList.get(0).getAttachment());
					if (elevator.getWbExtUrl() != null && elevator.getWbExtUrl().size() > 0) {
						PartWordUrlVo partWordUrlVo = JSON.parseArray(JSON.toJSONString(elevator.getWbExtUrl()), PartWordUrlVo.class).get(0);
						partWordUrlVo.setUrl(Convert.toStr(jsonObject.get("url")));
						elevator.setWbExtUrlDate(attachmentHistoryList.get(0).getCreateTime());
						partWordUrlVos.add(partWordUrlVo);
					} else {
						PartWordUrlVo partWordUrlVo = new PartWordUrlVo();
						partWordUrlVo.setUrl(Convert.toStr(jsonObject.get("url")));
						partWordUrlVo.setType("image");
						elevator.setWbExtUrlDate(attachmentHistoryList.get(0).getCreateTime());
						partWordUrlVos.add(partWordUrlVo);
					}
				}
				elevator.setWbExtUrl(partWordUrlVos);
				elevatorService.updateById(elevator);
			} else if (attachmentHistory.getStatus() == ElevatorAttachmentEnum.ELEVATOR_NUM_IMG.getStatus()) {
				List<ElevatorAttachmentHistory> attachmentHistoryList = listMap.get(ElevatorAttachmentEnum.ELEVATOR_NUM_IMG.getStatus());
				List<PartWordUrlVo> partWordUrlVos = new ArrayList<>(1);
				ElevatorDetail elevatorDetail = elevatorDetailService.getOne(Wrappers.<ElevatorDetail>lambdaQuery().eq(ElevatorDetail::getElevatorId, attachmentHistory.getElevatorId()));
				if (attachmentHistoryList != null && attachmentHistoryList.size() > 0) {
					JSONObject jsonObject = JSON.parseObject(attachmentHistoryList.get(0).getAttachment());
					if (elevatorDetail.getElevatorNumImg() != null && elevatorDetail.getElevatorNumImg().size() > 0) {
						PartWordUrlVo partWordUrlVo = JSON.parseArray(JSON.toJSONString(elevatorDetail.getElevatorNumImg()), PartWordUrlVo.class).get(0);
						partWordUrlVo.setUrl(Convert.toStr(jsonObject.get("url")));
						elevatorDetail.setElevatorNumImgDate(attachmentHistoryList.get(0).getCreateTime());
						partWordUrlVos.add(partWordUrlVo);
					} else {
						PartWordUrlVo partWordUrlVo = new PartWordUrlVo();
						partWordUrlVo.setUrl(Convert.toStr(jsonObject.get("url")));
						partWordUrlVo.setType("image");
						elevatorDetail.setElevatorNumImgDate(attachmentHistoryList.get(0).getCreateTime());
						partWordUrlVos.add(partWordUrlVo);
					}
				}
				elevatorDetail.setElevatorNumImg(partWordUrlVos);
				elevatorDetailService.updateById(elevatorDetail);
			} else if (attachmentHistory.getStatus() == ElevatorAttachmentEnum.BX_IMG.getStatus()) {
				List<ElevatorAttachmentHistory> attachmentHistoryList = listMap.get(ElevatorAttachmentEnum.BX_IMG.getStatus());
				List<PartWordUrlVo> partWordUrlVos = new ArrayList<>(1);
				if (attachmentHistoryList != null && attachmentHistoryList.size() > 0) {
					JSONObject jsonObject = JSON.parseObject(attachmentHistoryList.get(0).getAttachment());
					if (elevator.getBxExtUrl() != null && elevator.getBxExtUrl().size() > 0) {
						PartWordUrlVo partWordUrlVo = JSON.parseArray(JSON.toJSONString(elevator.getBxExtUrl()), PartWordUrlVo.class).get(0);
						partWordUrlVo.setUrl(Convert.toStr(jsonObject.get("url")));
						elevator.setBxExtUrlDate(attachmentHistoryList.get(0).getCreateTime());
						partWordUrlVos.add(partWordUrlVo);
					} else {
						PartWordUrlVo partWordUrlVo = new PartWordUrlVo();
						partWordUrlVo.setUrl(Convert.toStr(jsonObject.get("url")));
						partWordUrlVo.setType("image");
						elevator.setWbExtUrlDate(attachmentHistoryList.get(0).getCreateTime());
						partWordUrlVos.add(partWordUrlVo);
					}
				}
				elevator.setBxExtUrl(partWordUrlVos);
				elevatorService.updateById(elevator);
			}
		}
		elevatorAttachmentHistoryService.removeById(id);
		elevatorService.elevatorInit(elevator);
		return R.status(true);
	}

	/**
	 * 删除 电梯-附件表，电梯一对多附件, 历史表
	 * 检验报告
	 */
	@PostMapping("/report/remove")
	@ApiOperationSupport(order = 22)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R<Boolean> removeReport(@RequestBody List<String> ids) {
		List<Long> targetIds = new ArrayList<>();
		for (String id : ids) {
			targetIds.add(Long.parseLong(id));
		}
		targetIds.forEach(elevatorAttachmentService::removeById);
		return R.status(true);
	}

	/**
	 * 电梯使用证列表
	 *
	 * @param elevatorId 电梯id
	 * @param startTime  开始时间
	 * @param endTime    结束时间
	 * @return 电梯使用证列表
	 */
	@GetMapping("/certify/page")
	@ApiOperationSupport(order = 31)
	@ApiOperation(value = "使用证列表", notes = "传入elevatorAttachmentHistory")
	public R<IPage<ElevatorAttachmentHistory>> certifyList(Long elevatorId, Date startTime, Date endTime, Query query, Integer type) {

		List<Integer> status = new ArrayList<>();
		if (type == null) {
			status.add(ElevatorAttachmentEnum.IMG.getStatus());
			status.add(ElevatorAttachmentEnum.NAME.getStatus());
			status.add(ElevatorAttachmentEnum.WB_EXT_IMG.getStatus());
			status.add(ElevatorAttachmentEnum.WB_PHONE_IMG.getStatus());
			status.add(ElevatorAttachmentEnum.ELEVATOR_NUM_IMG.getStatus());
			status.add(ElevatorAttachmentEnum.BX_IMG.getStatus());
		} else {
			status.add(type);
		}
		IPage<ElevatorAttachmentHistory> page = elevatorAttachmentHistoryService.page(Condition.getPage(query),
			new LambdaQueryWrapper<ElevatorAttachmentHistory>()
				.eq(ElevatorAttachmentHistory::getElevatorId, elevatorId)
				.between(Func.isNotEmpty(startTime), ElevatorAttachmentHistory::getCreateTime, startTime, endTime)
				.in(BaseEntity::getStatus, status)
				.orderByDesc(ElevatorAttachmentHistory::getCreateTime)
		);
		List<ElevatorAttachmentHistory> records = page.getRecords();
		records.forEach(i -> {
			if (!Func.isNull(i.getCreateUser())) {
				User subUser = userService.getById(i.getCreateUser());
				i.setSubmitUser(subUser.getRealName());
			}
		});
		page.setRecords(records);
		return R.data(page);
	}

	/**
	 * 分页 电梯-附件表，电梯一对多附件, 历史表
	 * 检验报告
	 */
	@GetMapping("/report/page")
	@ApiOperationSupport(order = 32)
	@ApiOperation(value = "分页", notes = "传入elevatorAttachmentHistory")
	public R<IPage<ElevatorAttachmentVO>> reportPage(
		Long elevatorId, Integer reportAttachmentType,
		Date reportAttachmentBeginTime, Date reportAttachmentEndTime, Query query,
		Date createTime, Date createEndTime, String reportAttachmentNum) {

		return R.data(elevatorAttachmentService.selectElevatorAttachmentReportPage(Condition.getPage(query), elevatorId, reportAttachmentType,
			reportAttachmentBeginTime, reportAttachmentEndTime,
			createTime, createEndTime, reportAttachmentNum
		));
	}

	/**
	 * 列表 电梯-附件表，电梯一对多附件, 历史表
	 * 检验报告
	 */
	@GetMapping("/report/list")
	@ApiOperationSupport(order = 33)
	@ApiOperation(value = "列表", notes = "传入elevatorAttachmentHistory")
	public R<List<ElevatorAttachmentVO>> list(ElevatorAttachmentReportPageDTO elevatorAttachmentReportPageDTO) {
		List<ElevatorAttachmentVO> list = elevatorAttachmentService.selectElevatorAttachmentReportList(elevatorAttachmentReportPageDTO);
		return R.data(list);
	}

	@GetMapping("/elevatorNameConfirm")
	@ApiOperationSupport(order = 34)
	@ApiOperation(value = "电梯铭牌审批确认", notes = "传入planId")
	public R<Boolean> elevatorNameConfirm(Long planId) {
		if(Func.isEmpty(planId)){
			throw new ServiceException("请传入工单id");
		}
		// 0. 验证参数，获取电梯id
		MaintainPlanContent currentPlan = planContentService.getById(planId);
		Long elevatorId = currentPlan.getElevatorId();
		// 避免测试环境极端数据导致getOne报错，使用list
		List<MaintainPlanContentExt> extList = planContentExtService.list(new LambdaQueryWrapper<MaintainPlanContentExt>()
			.eq(MaintainPlanContentExt::getPlanId, planId)
			.eq(BaseEntity::getIsDeleted, 0)
		);
		if(Func.isEmpty(currentPlan) || Func.isEmpty(elevatorId) || Func.isEmpty(extList)){
			return R.data(Boolean.FALSE);
		}
		MaintainPlanContentExt maintainPlanContentExt = extList.get(0);
		// 1. 根据梯id新增elevatorAttachmentHistory记录，更新铭牌字段
		List<ElevatorAttachmentHistory> elevatorAttachmentHistoryList = elevatorAttachmentHistoryService.list(
			new LambdaQueryWrapper<ElevatorAttachmentHistory>()
				.eq(ElevatorAttachmentHistory::getElevatorId, elevatorId)
				.eq(ElevatorAttachmentHistory::getStatus, ElevatorAttachmentEnum.NAME.getStatus())
				.eq(BaseEntity::getIsDeleted, 0)
				.orderByDesc(ElevatorAttachmentHistory::getCreateTime)
		);
		if(Func.isEmpty(elevatorAttachmentHistoryList)){
			ElevatorAttachmentHistory elevatorAttachmentHistory = new ElevatorAttachmentHistory();
			elevatorAttachmentHistory.setElevatorId(elevatorId);
			elevatorAttachmentHistory.setStatus(ElevatorAttachmentEnum.NAME.getStatus());
			elevatorAttachmentHistory.setAttachment(maintainPlanContentExt.getElevatorNameAttachment());
			return R.data(elevatorAttachmentHistoryService.save(elevatorAttachmentHistory));
		}
		return R.data(Boolean.FALSE);
	}

}
